package com.ra.dao;

import java.util.List;
import java.util.ArrayList;

import org.apache.log4j.Logger;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.util.Version;
import org.hibernate.Query;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.Session;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;

import com.ra.dao.exceptions.InvalidSearchException;
import com.ra.model.product.Product;

final public class ProductDAOImpl extends AbstractDAO implements ProductDAO {
	private static final Logger logger = Logger.getLogger(ProductDAOImpl.class);

	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public void createProduct(Product product) {
		Session session = getSessionFactory().getCurrentSession();
		session.save(product);
	}

	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
	public Product getProduct(Long id) {
		Session session = getSessionFactory().getCurrentSession();
		return (Product) session.load(Product.class, id);
	}
	
	@Transactional(propagation=Propagation.REQUIRED, readOnly=true)
    public List<Product> searchProducts(String searchString) throws InvalidSearchException {
	    Session session = getSessionFactory().getCurrentSession();
        FullTextSession ftSession = Search.createFullTextSession(session);
        String[] productFields = new String[]{"productCategory", 
        		                              "productSubcategory", 
        		                              "productName", 
        		                              "productDescription"};
        
        QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_29, 
                                                       productFields, 
                                                       new StandardAnalyzer(Version.LUCENE_29));
        
        Query query = null;
        try {
            query = ftSession.createFullTextQuery(parser.parse(searchString), Product.class);
        } catch (ParseException pe) {
        	logger.error(pe.toString());
        	throw new InvalidSearchException(pe.toString());
        }
        
        List<Product> matchingProducts = new ArrayList<Product>();
        for (Object result: query.list()) {
        	Product product = (Product) result;
        	matchingProducts.add(product);
            logger.debug(product.getName() + ": " + product.getDescription());	
        }
        
        return matchingProducts;
    }
    
    public void createProduct(String code, String name, String description) {
    	return;
    }

	@Override
	public List<Product> getAllProducts() {
		// TODO Auto-generated method stub
		return null;
	}
}
